package com.sihan.swvp.sync.video;

import java.io.File;
import java.io.FileFilter;
import java.util.Calendar;
import java.util.Date;

import javax.annotation.PostConstruct;

import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.springframework.beans.factory.annotation.Autowired;

import com.sihan.swvp.common.CommonUtil;
import com.sihan.swvp.common.MD5Util;
import com.sihan.swvp.common.Mp4Util;
import com.sihan.swvp.entity.video.VideoSyn;
import com.sihan.swvp.service.sys.LogService;
import com.sihan.swvp.service.sys.SyncService;
import com.sihan.swvp.service.video.VideoSynService;
import com.sihan.swvp.sync.Synchronizer;

/**
 * 视频同步器
 * @author jch
 *
 */
public class VideoSynchronizer extends Synchronizer implements FileAlterationListener{
	
	//开始标识，标识第一次执行同步
	public static boolean start = false;
	//原始路径
	public String srcdir;
	//相对路径
	public String syncdir;
	//同步间隔
	public int interval = 10000;
	//最大同步时间，用于第一次同步
	public int maxdays = 30;
	
	@Autowired
	public SyncService syncService;
	@Autowired
	public VideoSynService videoSynService;
	@Autowired
	public LogService logService;
	
	public VideoSynchronizer(){
	
	}
	
	/**
	 * 初始化方法
	 */
	@PostConstruct
	public void init(){
    	Date starttime = getLastDate();
		if(!start){
			try {
				FileAlterationObserver observer = new FileAlterationObserver(new File(MD5Util.reversibleMD5Decode(srcdir)),new FileFilter(){
					@Override
					public boolean accept(File f) {
						
						return f.isDirectory() || f.getName().toLowerCase().endsWith(".mp4");
					}});
				observer.addListener(this);
				FileAlterationMonitor mnt = new FileAlterationMonitor(3000,observer);
				mnt.start();
				
				start = true;
			} catch (Exception e) {
				
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.exit(0);
			}
			
			sync(starttime,null);
			
			//syncService.updateSyncTime(jobid, starttime,"成功",true);
		}
	}
	
	@Override
	public void sync() {
    	Date syncDate = new Date();
    	Date starttime = getLastDate();
		sync(starttime,syncDate);
	}
	
	
	@Override
	public void sync(Date starttime, Date endtime) {
		// TODO Auto-generated method stub
		File srcfile = new File(MD5Util.reversibleMD5Decode(srcdir));
		if(!srcfile.exists() || !srcfile.isDirectory()){
			logService.addSystemLog("视频同步", "同步", 0,"没有找到同步目录：",MD5Util.reversibleMD5Decode(srcdir));
			System.out.println("没有找到同步目录：" + MD5Util.reversibleMD5Decode(srcdir));
		}
		else{
			forEachDir(srcfile,starttime,endtime);
			logService.addSystemLog("视频同步", "同步", 0, 
					CommonUtil.date2string(new Date()),"系统完成扫描",
					CommonUtil.date2string(starttime), "至",
					CommonUtil.date2string(null == endtime ? new Date() : endtime),"的视频。");
			syncService.updateSyncTime(jobid, endtime,"成功",true);
		}
	}
	
	/**
	 * 路径遍历
	 * @param dir 目录
	 * @param start 开始时间
	 * @param end 结束时间
	 */
	public void forEachDir(File dir,Date start, Date end){
		File[] flist = dir.listFiles(new Mp4Filter(start,end));
		
		for (File file : flist) {
			//将文件内容保存到数据库
			if(file.isDirectory()){
				
				forEachDir(file,start,end);
			}
			else{
				
				VideoSyn v= file2Entity(file);
				videoSynService.addVideosyn(v);
			}
		}
	}
	
	/**
	 * 视频文件名格式：时间_任务ID_角色ID_阶段ID_其他.mp4
	 * @param file
	 * @return
	 */
	public VideoSyn file2Entity(File file){
		File srcdirf = new File(MD5Util.reversibleMD5Decode(srcdir));
		VideoSyn v = new VideoSyn();
//		v.setTask_id(null);
//		v.setBz_id(null);
//		v.setRole_id(null);
//		v.setStage_id(null);
		v.setName(file.getName());
//		v.setStarttime(null);
//		v.setEndtime(null);
		v.setStatus(0);
		v.setSyntime(new Date());
		v.setRawpath(file.getAbsolutePath());
		v.setUpuser(0l);
		String relative = file.getAbsolutePath().replace(srcdirf.getAbsolutePath(), "");
		String synpath = "video\\" + relative;
		v.setSynpath(synpath);
		v.setLocpath(MD5Util.reversibleMD5Decode(syncdir)+File.separator+relative);
		v.setCjsb(getRootDir(srcdirf,file));
		
		String[] s = v.getName().replace(".mp4", "").replace(".MP4", "").split("_");
		if(s.length > 3){
//			v.setStarttime(CommonUtil.o2date(s[0],"yyyyMMddHHmmss"));
//			v.setTask_id(s[1]);
//			v.setRole_id(CommonUtil.o2int(s[2]));
//			v.setStage_id(CommonUtil.o2int(s[3]));
			v.setStarttime(CommonUtil.o2date(s[5],"yyyyMMddHHmmss"));
			v.setTask_id(s[0]);
			v.setTaskType(Integer.valueOf(s[1]));
			v.setBz_id(Integer.valueOf(s[2]));
			v.setRole_id(Integer.valueOf(s[3]));
			v.setStage_id(Integer.valueOf(s[4]));
		}
		else{
			try {
				v.setStarttime(CommonUtil.o2date(v.getName().substring(0, 14),"yyyyMMddHHmmss"));
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		
		long duration = Mp4Util.getDuration(file);
		v.setVideotime(duration);
		if(duration > 0){
			Date starttime = v.getStarttime();
			if(null != starttime){
				Date endtime = CommonUtil.dateAdd(starttime, Calendar.MILLISECOND, (int)duration);
				v.setEndtime(endtime);
			}
			
			try {
				final File sf = file;
				final File tf = new File(MD5Util.reversibleMD5Decode(syncdir),relative);
				new Thread(){
					@Override
					public void run() {
						try {
							Mp4Util.copy(sf, tf);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}.start();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return v;
	}
	
	
	public String getRootDir(File srcdirf,File file){
		String root = "";
		File temp = file;
		while(!file.getParentFile().equals(srcdirf)){
			if(temp == null || srcdirf.equals(temp.getParentFile().getParentFile())){
				root = temp.getParentFile().getName();
				break;
			}
			
			temp = temp.getParentFile();
		}
		
		return root;
	}
	
	/**
	 * 获取最后更新时间
	 * @return 时间字符串
	 */
	public String getLastTime(){
		String time = syncService.getLastSyncTime(jobid);
		if(null == time){
			Date date = CommonUtil.dateAdd(new Date(), Calendar.DATE, -maxdays);
			time = CommonUtil.date2string(date);
		}
		
		return time;
	}
	
	/**
	 * 获取最后更新时间
	 * @return 时间
	 */
	public Date getLastDate(){
		String time = syncService.getLastSyncTime(jobid);
		if(null == time){
			Date date = CommonUtil.dateAdd(new Date(), Calendar.DATE, -maxdays);
			
			return date;
		}
		
		return CommonUtil.o2date(time);
	}
	
	
	
	public void onStart(FileAlterationObserver observer) {
		
//		System.out.println("onStart");
	}
	
	public void onDirectoryCreate(File directory) {
		
		System.out.println("onDirectoryCreate:" +  directory.getName());
	}

	
	public void onDirectoryChange(File directory) {
		System.out.println("onDirectoryChange:" + directory.getName());
	}

	
	public void onDirectoryDelete(File directory) {
		System.out.println("onDirectoryDelete:" + directory.getName());
	}

	
	public void onFileCreate(File file) {
		System.out.println("onFileCreate:" + file.getName());
		
		//保持到数据库
		Date date = new Date();
		VideoSyn v= file2Entity(file);
		
		videoSynService.addVideosyn(v);
		syncService.updateSyncTime(jobid, date,"成功",true);
		logService.addSystemLog("视频同步", "同步", 0,
				"监听到创建了视频文件",file.getAbsolutePath(),"，并同步到平台。");
	}

	
	public void onFileChange(File file) {
//		System.out.println("onFileChange : " + file.getName());
		long duration = Mp4Util.getDuration(file);
		if(duration > 0){
			VideoSyn v= file2Entity(file);
			videoSynService.addVideosyn(v);
		}
	}

	
	public void onFileDelete(File file) {
		
		System.out.println("onFileDelete :" + file.getName());
	}

	
	public void onStop(FileAlterationObserver observer) {
		
//		System.out.println("onStop");
	}
	

	public String getSrcdir() {
		
		return srcdir;
	}

	public void setSrcdir(String srcdir) {
		System.out.println(srcdir);
		this.srcdir = srcdir;
	}

	public int getMaxdays() {
		return maxdays;
	}

	public void setMaxdays(int maxdays) {
		this.maxdays = maxdays;
	}

	public SyncService getSyncService() {
		return syncService;
	}

	public void setSyncService(SyncService syncService) {
		this.syncService = syncService;
	}

	public int getInterval() {
		return interval;
	}

	public void setInterval(int interval) {
		this.interval = interval;
	}

	public String getSyncdir() {
		return syncdir;
	}

	public void setSyncdir(String syncdir) {
		this.syncdir = syncdir;
	}
	
//	public static void main(String[] args) {
//		String s = "20161213130215qewqeq";
//		System.out.println(s.substring(0, 14));
//		
//		Date d = CommonUtil.o2date(s.substring(0, 14),"yyyyMMddHms");
//		System.out.println(d);
//	}
}
